package com.coder4j.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.coder4j.starter.web.BaseException;
import com.coder4j.starter.web.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;

/**
 * 阿里巴巴 easyExcel 工具类
 *
 * @author Keller
 * @date 2022-07-26 13:31:39
 */
@Slf4j
public class EasyExcelUtils {

    /**
     * 获取下载文件的输出流
     * @param response
     * @param fileName
     * @return
     */
    public static ServletOutputStream getOutputStream(HttpServletResponse response,String fileName){
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Response-Type", "Download");
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            throw BaseException.error("导出异常");
        }
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        try {
            return response.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
            throw BaseException.error("导出异常");
        }
    }

    /**
     * 按照类模型导出
     * @param response
     * @param fileName
     * @param list
     * @param <T>
     */
    public static <T> void exportClass(HttpServletResponse response, String fileName, List<T> list) {

        try {
            if (list == null || list.isEmpty()) {
                throw BaseException.error("没有数据");
            }

            EasyExcel.write(getOutputStream(response,fileName), list.get(0).getClass())
                    .sheet("Sheet1").doWrite(list);
        } catch (Exception e) {
            log.error("{}", e);
            response.setHeader("Content-Type", "application/json");
            response.setCharacterEncoding("UTF-8");
            try {
                response.getWriter().write(JSON.toJSONString(R.error("导出失败：" + e.getMessage())));
            } catch (IOException e1) {
                log.error("{}", e1);
            }
        }
    }

    /**
     * 导出自定义数据，用于标题、列数，都不确定的情况
     * @param response
     * @param fileName
     * @param headList 自定义表头
     * @param dataList 自定义数据
     */
    public static void exportCustomer(HttpServletResponse response, String fileName, List<List<String>> headList, List<List<String>> dataList) {

        try {
            if (dataList == null || dataList.isEmpty()) {
                throw BaseException.error("没有数据");
            }

            // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
            HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                    new HorizontalCellStyleStrategy(getHeadStyle(), new WriteCellStyle());

            EasyExcel.write(getOutputStream(response,fileName))
                    .autoCloseStream(Boolean.FALSE)
                    .head(headList)

                    // 第一行大标题样式设置
//                    .registerWriteHandler(new SheetWriteHandlerUtil(fileName))
                    //设置默认样式及写入头信息开始的行数
//                    .useDefaultStyle(true).relativeHeadRowIndex(1)
                    // 表头、内容样式设置
//                    .registerWriteHandler(horizontalCellStyleStrategy)
                    // 统一列宽,如需设置自动列宽则new LongestMatchColumnWidthStyleStrategy()
                    .registerWriteHandler(new SimpleColumnWidthStyleStrategy(20))
                    .sheet("Sheet1")
                    .doWrite(dataList);
        } catch (Exception e) {
            log.error("{}", e);
            response.setHeader("Content-Type", "application/json");
            response.setCharacterEncoding("UTF-8");
            try {
                response.getWriter().write(JSON.toJSONString(R.error("导出失败：" + e.getMessage())));
            } catch (IOException e1) {
                log.error("{}", e1);
            }
        }
    }


    public static WriteCellStyle getHeadStyle(){
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景颜色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 字体
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontName("黑体");//设置字体名字
        headWriteFont.setFontHeightInPoints((short)15);//设置字体大小
        headWriteFont.setBold(true);//字体加粗
        headWriteCellStyle.setWriteFont(headWriteFont); //在样式用应用设置的字体;
        // 样式
        headWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
        headWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
        headWriteCellStyle.setBorderLeft(BorderStyle.THIN);  //设置左边框;
        headWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
        headWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
        headWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
        headWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
        headWriteCellStyle.setTopBorderColor((short) 0); //设置顶边框颜色;
        headWriteCellStyle.setWrapped(true);  //设置自动换行;
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);//设置水平对齐的样式为居中对齐;
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);  //设置垂直对齐的样式为居中对齐;
        //        headWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适

        return headWriteCellStyle;
    }




}
